package org.lex.filter.swing;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;

import org.lex.filter.Filter;
import org.lex.filter.Filters;
import org.lex.filter.RangeFilter;
import org.lex.swing.Swings;
import org.lex.swing.widgets.JLabelSeparator;
import org.lex.utils.text.SizeFormat;
import org.lex.utils.text.SizeFormat.Style;
import org.lex.utils.text.SizeUnit;


public class SizeFilterPane extends AbstractFilterPane<Long> {
	private static final String[] MASKS = { "at least", "at most" };
	private static final long small = SizeUnit.convert(500, SizeUnit.K);
	private static final long medium = SizeUnit.convert(5, SizeUnit.M);
	private JLabelSeparator sizeLabel = null;
	private JRadioButton notRememberRadioButton = null;
	private JRadioButton smallRadioButton = null;
	private JRadioButton mediumRadioButton = null;
	private JRadioButton largeRadioButton = null;
	private JRadioButton specifyRadioButton = null;
	private JPanel specifyPane = null;
	private JComboBox maskComboBox = null;
	private JSpinner sizeSpinner = null;
	private JComboBox unitComboBox = null;
	private JPanel gluePane = null;
	private JLabel unitLabel = null;

	public SizeFilterPane() {
		super();
		initialize();
	}

	public String getTitle() {
		return "Size";
	}

	public Filter<Long> getFilter() {
		Filter<Long> filter = null;
		if (true == this.notRememberRadioButton.isSelected())
			filter = Filters.acceptAllFilter();
		else if (true == this.smallRadioButton.isSelected())
			filter = new RangeFilter<Long>(small, RangeFilter.Mask.LE);
		else if (true == this.mediumRadioButton.isSelected())
			filter = new RangeFilter<Long>(medium, RangeFilter.Mask.LE);
		else if (true == this.largeRadioButton.isSelected())
			filter = new RangeFilter<Long>(medium, RangeFilter.Mask.GT);
		else {
			// specify size
			RangeFilter.Mask mask = null;
			if (0 == this.maskComboBox.getSelectedIndex())
				mask = RangeFilter.Mask.GE;
			else
				mask = RangeFilter.Mask.LE;
			long size = ((Number) this.sizeSpinner.getValue()).longValue();
			SizeUnit unit = SizeUnit.values()[unitComboBox.getSelectedIndex()];
			filter = new RangeFilter<Long>(SizeUnit.convert(size, unit), mask);
		}
		return filter;
	}

	// =======================
	private void initialize() {
		GridBagConstraints gridBagConstraints31 = new GridBagConstraints();
		gridBagConstraints31.gridx = 0;
		gridBagConstraints31.fill = GridBagConstraints.BOTH;
		gridBagConstraints31.weightx = 1.0;
		gridBagConstraints31.weighty = 1.0;
		gridBagConstraints31.gridwidth = 2;
		gridBagConstraints31.gridy = 7;
		GridBagConstraints gridBagConstraints6 = new GridBagConstraints();
		gridBagConstraints6.gridx = 0;
		gridBagConstraints6.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints6.weightx = 1.0;
		gridBagConstraints6.gridwidth = 2;
		gridBagConstraints6.insets = new Insets(0, 28, 0, 7);
		gridBagConstraints6.gridy = 6;
		GridBagConstraints gridBagConstraints5 = new GridBagConstraints();
		gridBagConstraints5.gridx = 0;
		gridBagConstraints5.anchor = GridBagConstraints.WEST;
		gridBagConstraints5.insets = new Insets(0, 6, 0, 0);
		gridBagConstraints5.gridy = 5;
		GridBagConstraints gridBagConstraints4 = new GridBagConstraints();
		gridBagConstraints4.gridx = 1;
		gridBagConstraints4.anchor = GridBagConstraints.WEST;
		gridBagConstraints4.insets = new Insets(0, 6, 0, 0);
		gridBagConstraints4.gridy = 3;
		GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
		gridBagConstraints3.gridx = 0;
		gridBagConstraints3.anchor = GridBagConstraints.WEST;
		gridBagConstraints3.insets = new Insets(0, 6, 0, 0);
		gridBagConstraints3.gridy = 3;
		GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
		gridBagConstraints2.gridx = 1;
		gridBagConstraints2.anchor = GridBagConstraints.WEST;
		gridBagConstraints2.insets = new Insets(0, 6, 0, 0);
		gridBagConstraints2.gridy = 1;
		GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
		gridBagConstraints1.gridx = 0;
		gridBagConstraints1.anchor = GridBagConstraints.WEST;
		gridBagConstraints1.insets = new Insets(0, 6, 0, 0);
		gridBagConstraints1.gridy = 1;
		GridBagConstraints gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.anchor = GridBagConstraints.WEST;
		gridBagConstraints.insets = new Insets(6, 12, 0, 5);
		gridBagConstraints.gridwidth = 2;
		gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints.gridy = 0;
		sizeLabel = new JLabelSeparator("What size is it?");
		this.setSize(300, 200);
		this.setLayout(new GridBagLayout());
		this.add(sizeLabel, gridBagConstraints);
		this.add(getNotRememberRadioButton(), gridBagConstraints1);
		this.add(getSmallRadioButton(), gridBagConstraints2);
		this.add(getMediumRadioButton(), gridBagConstraints3);
		this.add(getLargeRadioButton(), gridBagConstraints4);
		this.add(getSpecifyRadioButton(), gridBagConstraints5);
		this.add(getSpecifyPane(), gridBagConstraints6);
		this.add(getGluePane(), gridBagConstraints31);
		Swings.createButtonGroup(this.notRememberRadioButton, this.smallRadioButton, this.mediumRadioButton, this.largeRadioButton,
				this.specifyRadioButton);
	}

	private JRadioButton getNotRememberRadioButton() {
		if (notRememberRadioButton == null) {
			notRememberRadioButton = new JRadioButton();
			notRememberRadioButton.setSelected(true);
			notRememberRadioButton.setText("Don't remember");
		}
		return notRememberRadioButton;
	}

	private JRadioButton getSmallRadioButton() {
		if (smallRadioButton == null) {
			smallRadioButton = new JRadioButton();
			String text = "Small ( " + RangeFilter.Mask.LE.symbol() + SizeFormat.format(small, SizeUnit.K, 2) + "B )";
			smallRadioButton.setText(text);
		}
		return smallRadioButton;
	}

	private JRadioButton getMediumRadioButton() {
		if (mediumRadioButton == null) {
			mediumRadioButton = new JRadioButton();
			String text = "Medium ( " + RangeFilter.Mask.LE.symbol() + SizeFormat.format(medium, SizeUnit.M, 2) + "B )";
			mediumRadioButton.setText(text);
		}
		return mediumRadioButton;
	}

	private JRadioButton getLargeRadioButton() {
		if (largeRadioButton == null) {
			largeRadioButton = new JRadioButton();
			String text = "Medium ( " + RangeFilter.Mask.GT.symbol() + SizeFormat.format(medium, SizeUnit.M, 2) + "B )";
			largeRadioButton.setText(text);
		}
		return largeRadioButton;
	}

	private JRadioButton getSpecifyRadioButton() {
		if (specifyRadioButton == null) {
			specifyRadioButton = new JRadioButton();
			specifyRadioButton.setText("Specify size");
			specifyRadioButton.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) {
					setSpecifyPaneEnabled(specifyRadioButton.isSelected());
				}
			});
		}
		return specifyRadioButton;
	}

	private void setSpecifyPaneEnabled(boolean b) {
		this.getMaskComboBox().setEnabled(b);
		this.getSizeSpinner().setEnabled(b);
		this.getUnitComboBox().setEnabled(b);
		this.unitLabel.setEnabled(b);
	}

	private JPanel getSpecifyPane() {
		if (specifyPane == null) {
			GridBagConstraints gridBagConstraints10 = new GridBagConstraints();
			gridBagConstraints10.gridx = 3;
			gridBagConstraints10.insets = new Insets(0, 6, 0, 5);
			gridBagConstraints10.fill = GridBagConstraints.NONE;
			gridBagConstraints10.weightx = 0.0;
			gridBagConstraints10.gridy = 0;
			unitLabel = new JLabel();
			unitLabel.setText("Byte");
			GridBagConstraints gridBagConstraints9 = new GridBagConstraints();
			gridBagConstraints9.fill = GridBagConstraints.NONE;
			gridBagConstraints9.gridy = 0;
			gridBagConstraints9.weightx = 0.0;
			gridBagConstraints9.anchor = GridBagConstraints.EAST;
			gridBagConstraints9.insets = new Insets(0, 6, 0, 0);
			gridBagConstraints9.gridx = 2;
			GridBagConstraints gridBagConstraints8 = new GridBagConstraints();
			gridBagConstraints8.fill = GridBagConstraints.VERTICAL;
			gridBagConstraints8.gridx = 1;
			gridBagConstraints8.gridy = 0;
			gridBagConstraints8.insets = new Insets(0, 6, 0, 0);
			gridBagConstraints8.weightx = 1.0;
			gridBagConstraints8.anchor = GridBagConstraints.WEST;
			gridBagConstraints8.ipadx = 60;
			gridBagConstraints8.weighty = 0.0;
			GridBagConstraints gridBagConstraints7 = new GridBagConstraints();
			gridBagConstraints7.fill = GridBagConstraints.NONE;
			gridBagConstraints7.gridx = 0;
			gridBagConstraints7.gridy = 0;
			gridBagConstraints7.anchor = GridBagConstraints.WEST;
			gridBagConstraints7.insets = new Insets(0, 0, 0, 0);
			gridBagConstraints7.weightx = 0.0;
			specifyPane = new JPanel();
			specifyPane.setLayout(new GridBagLayout());
			specifyPane.add(getMaskComboBox(), gridBagConstraints7);
			specifyPane.add(getSizeSpinner(), gridBagConstraints8);
			specifyPane.add(getUnitComboBox(), gridBagConstraints9);
			specifyPane.add(unitLabel, gridBagConstraints10);
			this.setSpecifyPaneEnabled(getSpecifyRadioButton().isSelected());
		}
		return specifyPane;
	}

	private JComboBox getMaskComboBox() {
		if (maskComboBox == null) {
			maskComboBox = new JComboBox();
			for (String mask : MASKS)
				maskComboBox.addItem(mask);
		}
		return maskComboBox;
	}

	private JSpinner getSizeSpinner() {
		if (sizeSpinner == null) {
			sizeSpinner = new JSpinner();
			sizeSpinner.setModel(new SpinnerNumberModel(1L, 0L, Long.MAX_VALUE, 1L));
		}
		return sizeSpinner;
	}

	private JComboBox getUnitComboBox() {
		if (unitComboBox == null) {
			unitComboBox = new JComboBox();
			for (SizeUnit unit : SizeUnit.values())
				unitComboBox.addItem(unit.getStyle(Style.UPCASE_FULL));
			unitComboBox.setSelectedIndex(SizeUnit.M.ordinal());
		}
		return unitComboBox;
	}

	private JPanel getGluePane() {
		if (gluePane == null) {
			gluePane = new JPanel();
			gluePane.setLayout(new GridBagLayout());
		}
		return gluePane;
	}
}
